package chapter8.section8;

//程序8-12：Stream流操作示例

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

class Account {
    String aid;
    int balance;

    public Account(String aid, int balance) {
        this.aid = aid;
        this.balance = balance;
    }

    public int getBalance() {
        return balance;
    }

    public String toString() {
        return "账号：" + aid + ",余额:" + balance;
    }

    @Override
    public boolean equals(Object obj) {
        // TODO Auto-generated method stub
        if (!(obj instanceof Account)) return false;
        else {
            Account acc = (Account) obj;
            return acc.aid.equals(this.aid) && (acc.balance == this.balance);
        }
    }

    @Override
    public int hashCode() {
        // TODO Auto-generated method stub
        return aid.hashCode() + balance;
    }
}

public class StreamDemo {
    public static void main(String[] args) {
        String words = "Great minds have purpose";
        List<String> wordsList = List.of(words.split(" "));
        int count = 0;
        for (String s : wordsList)// 传统统计方法
            if (s.length() > 4) count++;
        System.out.println("count:" + count);
        long count2 = wordsList.stream().filter(w -> w.length() > 4).count();// 利用stream和lambda表达式方式
        System.out.println("count:" + count2);

        ArrayList<Account> accList = new ArrayList<>();
        accList.add(new Account("a01", 3000));
        accList.add(new Account("a02", 8000));
        accList.add(new Account("a03", 7000));
        accList.add(new Account("a04", 5000));
        Stream<Account> stream = accList.stream();
        stream.filter(e -> e.getBalance() > 4000).forEach(System.out::println);// 输出余额大于4000的帐户信息
        // 筛选重复的"a03"和"a04"
        System.out.println();
        accList.add(new Account("a04", 5000));
        accList.add(new Account("a03", 7000));
        accList.stream().distinct().forEach(System.out::println);
        // 将字符串转换为大写
        System.out.println();
        List<String> list1 = Arrays.asList("aa", "bb", "cc", "dd");
        list1.stream().map(str -> str.toUpperCase()).forEach((a) -> System.out.print(a + " "));
        System.out.println();
        // 将元素按照从小到大排序
        List<Integer> list2 = Arrays.asList(12, 43, 65, 34, 87, 0, -98, 7);
        list2.stream().sorted().forEach((a) -> System.out.print(a + " "));
        System.out.println();
        // 筛选重复的元素、按照余额排序后输出
        accList.stream().distinct().sorted((e1, e2) -> {
            return Integer.compare(e1.getBalance(), e2.getBalance());
        }).forEach(System.out::println);
        // 检查是否有余额超过10000的帐户
        boolean anyMatch = accList.stream().anyMatch(e -> e.getBalance() > 10000);
        System.out.println(anyMatch);

        // 找到最低余额的帐户
        Optional<Account> minAcc = accList.stream().min((e1, e2) -> Integer.compare(e1.getBalance(), e2.getBalance()));// 关于Optional类见第9章
        System.out.println(minAcc.get());

//     计算1-10的自然数的和
        List<Integer> list3 = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Integer sum = list3.stream().reduce(0, Integer::sum);
        System.out.println("1到10的累加和为：" + sum);
        // 计算所有账户的余额的累加和
        Optional<Integer> sumBalance = accList.stream().map(Account::getBalance).reduce((e1, e2) -> e1 + e2);
        System.out.println("所有账户累加和为：" + sumBalance.get());
        // 查找余额大于7000的帐户员工，结果返回为一个List
        List<Account> resList = accList.stream().filter(e -> e.getBalance() > 7000).collect(Collectors.toList());
        // 查找结果输出
        resList.stream().forEach(System.out::println);
    }
}
